﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Globalization;
using System.IO;
using System.Diagnostics;
using System.Security.Permissions;
using System.Threading;

namespace AnaViewer
{ 
    static class Program
    {
        static AnaSubject subject;

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
        static void Main(string[] args)
        {
#if !DEBUG
            AppDomain currentDomain = AppDomain.CurrentDomain;
            currentDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs e) { HandleError(null); };
            Application.ThreadException += delegate(object sender, ThreadExceptionEventArgs e) { HandleError(e.Exception); };
#endif
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            if (args.Length > 0)
            {
                string longArg = args[0].Trim().ToLower(CultureInfo.InvariantCulture);
                if (longArg == "-anaviewer")//-AnaViewer
                {//运行 语录阅览器
                    RunAnaViewer();
                }
                else if (longArg == "-screensaver")//-ScreenSaver
                {//运行 屏幕保护程序
                    RunScreenSaver();
                }
                else if (longArg == "/install")//“/Install”
                {//安装
                    //运行 屏保安装程序
                    RunScreenSaverInstaller();
                }
                else if (longArg == "/uninstall")//“/Uninstall”
                {//卸载
                    //运行 屏保卸载程序
                    RunScreenSaverUninstall();
                    AutoStartHelper.AutoStartSwitch(false);//有可能用户设置了启动项，尝试删除启动项。
                }
                else
                {//屏幕保护程序的执行参数
                    try
                    {
                        string argPrefix;
                        int argHandle = 0; // 如果参数中没有指定数值，则为 0
                        ParseArgsToPrefixAndArgInt(args, out argPrefix, out argHandle);
                        // 获取双字符命令行参数
                        //string arg = args[0].ToLower(CultureInfo.InvariantCulture).Trim().Substring(0, 2);
                        switch (argPrefix)//arg)
                        {
                            case "/a": // 密码对话框，在 Win2000以上系统无效。
                                break;
                            case "/c":// 显示选项对话框 ShowOptions
                                RunOptions();
                                break;
                            case "/p":// 不要进行任何预览操作
                                if (argHandle == 0)//没有发现 Handle，则启动全屏的屏保，同“/s”参数
                                    RunScreenSaver();
                                else
                                    MiniPreview.DoMiniPreview(argHandle);
                                break;
                            case "/s":// 显示屏幕保护程序窗体 ShowScreenSaver
                                RunScreenSaver();
                                break;
                            default:
                                //MessageBox.Show("无效的命令行参数 :" + arg, "无效的命令行参数", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                RunAnaViewer();
                                break;
                        }
                    }
                    catch
                    {
                        // Just exit because this is a screensaver for unattended operation. We don't want a message
                        // and we want to exit if anything goes wrong.
                    }
                }
            }
            else
            {
                // 如果未传入参数，则显示屏幕保护程序
                //RunScreenSaver();
                RunOptions();
            }
        }

        /// <summary>
        /// 处理未知的致命异常。
        /// </summary>
        static void HandleError(Exception ex)
        {
            //string echoText = Properties.Resources.UnhandledExceptionEchoText;
            //DialogResult result = MessageBox.Show(echoText, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);

            ErrorReportForm form = new ErrorReportForm();
            form.ShowDialog();
        }

        private static void ParseArgsToPrefixAndArgInt(string[] args, out string argPrefix, out int argHandle)
        {
            string curArg;
            char[] SpacesOrColons =  { ' ', ':' };

            switch (args.Length)
            {
                case 0: // Nothing on command line, so just start the screensaver.
                    argPrefix = "/s";
                    argHandle = 0;
                    break;
                case 1:
                    curArg = args[0];
                    argPrefix = curArg.Substring(0, 2);
                    curArg = curArg.Replace(argPrefix, ""); // Drop the slash /? part.
                    curArg = curArg.Trim(SpacesOrColons); // Remove colons and spaces.
                    int tempInt = 0;
                    if (int.TryParse(curArg, out tempInt))// if empty return zero. else get handle.
                        argHandle = tempInt;
                    else
                        argHandle = 0;
                    break;
                case 2:
                    argPrefix = args[0].Substring(0, 2);
                    argHandle = int.Parse(args[1].ToString());
                    break;
                default:
                    argHandle = 0;
                    argPrefix = "";
                    break;

            }
        }


        const string scrFileName = "语录.scr";
        /// <summary>
        /// 语录 屏幕保护程序 可执行文件完整路径。
        /// </summary>
        static string ScrFileFullName
        {
            get
            {
                //return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), scrFileName);
                return Path.Combine(Application.StartupPath, scrFileName);
            }
        }

        /// <summary>
        /// 运行 屏幕保护程序 安装程序。
        /// </summary>
        static void RunScreenSaverInstaller()
        {
            string oldPath = Application.ExecutablePath;
            string newPath = ScrFileFullName;

            if (File.Exists(oldPath))
            {
                try
                {
                    File.Copy(oldPath, newPath, true);

                    Process.Start("rundll32.exe", string.Format("desk.cpl,InstallScreenSaver {0}", newPath));
                }
                catch (Exception ex)
                {
                    MessageBox.Show("“语录”屏幕保护程序安装失败。信息:"+ex.Message,"错误");
                }
            }
 
        }
        /// <summary>
        /// 运行 屏幕保护程序 卸载程序。
        /// </summary>
        static void RunScreenSaverUninstall()
        {
            string newPath = ScrFileFullName;

            if (File.Exists(newPath))
            {
                try
                {
                    File.Delete(newPath);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("“语录”屏幕保护程序卸载失败。信息:" + ex.Message, "错误");
                }
            }
 
        }
        /// <summary>
        /// 运行 配置程序。
        /// </summary>
        static void RunOptions()
        {
            OptionsForm optionsForm = new OptionsForm();
            optionsForm.Text = Application.ProductName + " 选项";
            optionsForm.StartPosition = FormStartPosition.CenterScreen;
            Application.Run(optionsForm);
        }
        /// <summary>
        /// 运行 屏幕保护程序。
        /// </summary>
        static void RunScreenSaver()
        {
            subject = new AnaSubject();
            ScreenSaverForm screenSaver = new ScreenSaverForm();
            screenSaver.Subject = subject;
            screenSaver.Load += delegate(object sender, EventArgs e) { subject.Load(); };
            screenSaver.FormClosing += delegate(object sender, FormClosingEventArgs e) { subject.Close(); };
            Application.Run(screenSaver);
        }


        #region RunAnaViewer
        /// <summary>
        /// 运行 语录阅览器。
        /// </summary>
        static void RunAnaViewer()
        {
            ////方法一
            //if (! SingleInstance.HandleRunningInstance())
            //    RunApplication();

            //方法二
            if (SingleInstance.CreateMutex())
            {//是第一个进程
                RunApplication();
                SingleInstance.ReleaseMutex();
            }
            else
            {//不是，则试着将第一个进程显示到前台
                if (!SingleInstance.HandleRunningInstance())//显示失败，这只显示一条错误信息
                {
                    string echo = string.Format("“{0}”已经在运行中。", Application.ProductName);//"已经有一个实例在运行中。"
                    MessageBox.Show(echo, "提示");

                }
            }
        }

        /// <summary>
        /// 启动应用程序
        /// </summary>
        static void RunApplication()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            subject = new AnaSubject();
            InitializeAnaForm();
            InitializeMainForm();
            anaForm.Load += delegate(object sender, EventArgs e) { subject.Load(); };
            anaForm.FormClosing += delegate(object sender, FormClosingEventArgs e) { subject.Close(); };

            if (!Properties.Settings.Default.HideMainFormWhenStart)
                mainForm.Show();
            Application.Run(anaForm);
        }
        #endregion

        #region AnaForm 初始化和显示方法
        static AnaForm anaForm;
        static void InitializeAnaForm()
        {
            anaForm = new AnaForm();
            anaForm.Subject = subject;
        }
        static void ShowAnaForm()
        {
            if (anaForm == null || anaForm.IsDisposed)
            {
                InitializeAnaForm();
                anaForm.Subject = subject;
            }

            if (anaForm.Visible)
                anaForm.Activate();
            else
                anaForm.Show();

            //if (anaForm.EmbedDesktop)
            //    Util.Win32.ToggleDesktop();
        }
        #endregion

        #region MainForm
        static MainForm mainForm;
        static void InitializeMainForm()
        {
            mainForm = new MainForm();
            mainForm.Subject = subject;
        }

        public static void ShowMainForm()
        {
            if (mainForm == null || mainForm.IsDisposed)
                InitializeMainForm();

            if (mainForm.Visible)
            {
                mainForm.Activate();
                mainForm.WindowState = FormWindowState.Normal;
            }
            else
            {
                mainForm.Show();
                mainForm.WindowState = FormWindowState.Normal;
            }
        }
        #endregion
    }
}